using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web;


[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.SyntaxHighlighter.css", "text/css")]

[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shCore.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushXml.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushVb.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushSql.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushRuby.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushPython.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushPhp.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushJScript.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushJava.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushDelphi.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushCss.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushCSharp.js", "text/javascript")]
[assembly: WebResource("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shBrushCpp.js", "text/javascript")]
namespace SharpPieces.Web.Controls
{
    public enum Language
    {
        CSharp,
        Delphi,
        JavaScript,
        Python,
        Sql,
        Xml,
        Cpp,
        Css,
        Java,
        Php,
        Ruby,
        VisualBasic
    }

    public class SyntaxHighlighter : SharpControl
    {
        //based on http://code.google.com/p/syntaxhighlighter/
        string template;
        private bool _embeddedStyleSheet;
        private Language _language;
        private bool _showGutter;
        private bool _showControls;
        private int _firstLine;
        private bool _showColumns;
        private bool _collapsed;
        private bool _useTextArea;

        public SyntaxHighlighter() : base("pre")
        {
            this.Init += new EventHandler(SyntaxHighlighter_Init);
            this.PreRender += new EventHandler(SyntaxHighlighter_PreRender);

            EmbeddedStyleSheet = true;
            ShowColumns = false;
            FirstLine = 1;
            ShowGutter = true;
            ShowControls = true;
        }
        public bool EmbeddedStyleSheet
        {
            get { return _embeddedStyleSheet; }
            set { _embeddedStyleSheet = value; }
        }

        public bool UseTextArea
        {
            get { return _useTextArea; }
            set 
            {
                _useTextArea = value;
                if (value)
                    _tagName = "textarea";
            }
        }

        public bool Collapsed
        {
            get { return _collapsed; }
            set { _collapsed = value; }
        }

        public Language Language
        {
            get { return _language; }
            set 
            {
                _language = value; 
            }
        }

        void SyntaxHighlighter_Init(object sender, EventArgs e)
        {
            //this.ContentTemplate.InstantiateIn(this);
        }

        void AddCssLink(string filePath)
        {
            string url = Page.ClientScript.GetWebResourceUrl(this.GetType(),filePath);
            bool found = false;

            foreach (Control ctl in Page.Header.Controls)
            {
                if (ctl is LiteralControl)
                {
                    if ((ctl as LiteralControl).Text.IndexOf(string.Format("href='{0}'", url)) > -1)
                    {
                        found = true;
                        break;
                    }
                }

            }

            if(!found)
                Page.Header.Controls.Add(new LiteralControl(string.Format("<link href='{0}' rel='stylesheet' type='text/css' />", url)));
        }

        void SyntaxHighlighter_PreRender(object sender, EventArgs e)
        {
            this.Controls.Clear();
            if(!this.UseTextArea) //no textarea -> escape xml
                this.Controls.Add(new LiteralControl(this.Page.Server.HtmlEncode(this.template.Trim())));
            else
                this.Controls.Add(new LiteralControl(this.template.Trim()));

            if(this.EmbeddedStyleSheet)
                AddCssLink("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.SyntaxHighlighter.css");

            this.Page.ClientScript.RegisterClientScriptInclude("coreHighlight", Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpPieces.Web.Controls.Resources.SyntaxHighlighter.shCore.js"));

            RegisterScriptLanguage(this.Language);

            this.Page.ClientScript.RegisterStartupScript(this.GetType(), "init_"+this.ClientID, 
                string.Format("dp.SyntaxHighlighter.HighlightAll('{0}', {1}, {2}, {5},{3},{4});", this.ClientID, ShowGutter.ToString().ToLower(),ShowControls.ToString().ToLower(),FirstLine, ShowColumns.ToString().ToLower(), Collapsed.ToString().ToLower()), true);
            this.Attributes.Add("name", ClientID);
        }

        private void RegisterScriptLanguage(Language language)
        {
            string code = "";

            switch (language)
            {
                case Language.CSharp:
                    code = "shBrushCSharp";
                    this.CssClass = "c-sharp";
                    break;

                case Language.Cpp:
                    code = "shBrushCpp";
                    this.CssClass = "cpp";
                    break;

                case Language.Delphi:
                    code = "shBrushDelphi";
                    this.CssClass = "delphi";
                    break;

                case Language.Css:
                    code = "shBrushCss";
                    this.CssClass = "css";
                    break;

                case Language.Java:
                    code = "shBrushJava";
                    this.CssClass = "java";
                    break;

                case Language.JavaScript:
                    code = "shBrushJScript";
                    this.CssClass = "js";
                    break;

                case Language.Php:
                    code = "shBrushPhp";
                    this.CssClass = "php";
                    break;

                case Language.Python:
                    code = "shBrushPython";
                    this.CssClass = "py";
                    break;

                case Language.Ruby:
                    code = "shBrushRuby";
                    this.CssClass = "ruby";
                    break;

                case Language.Sql:
                    code = "shBrushSql";
                    this.CssClass = "sql";
                    break;

                case Language.VisualBasic:
                    code = "shBrushVb";
                    this.CssClass = "vb";
                    break;

                case Language.Xml:
                    code = "shBrushXml";
                    this.CssClass = "xml";
                    break;
                   
                default: break;
            }

            this.Page.ClientScript.RegisterClientScriptInclude("highlight_"+this.CssClass, Page.ClientScript.GetWebResourceUrl(this.GetType(), string.Format("SharpPieces.Web.Controls.Resources.SyntaxHighlighter.{0}.js", code)));
        }

        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public string ContentTemplate
        {
            get { return this.template; }
            set { this.template = value; }
        }

        public bool ShowColumns
        {
            get { return _showColumns; }
            set { _showColumns = value; }
        }

        public int FirstLine
        {
            get { return _firstLine; }
            set { _firstLine = value; }
        }

        public bool ShowControls
        {
            get { return _showControls; }
            set { _showControls = value; }
        }

        public bool ShowGutter
        {
            get { return _showGutter; }
            set { _showGutter = value; }
        }

        public static Language LanguageFromExtension(string extension)
        {
            switch (extension.ToLower())
            {
                case ".cs":
                    return Language.CSharp;
                case ".vb":
                    return Language.VisualBasic;
                case ".aspx":
                case ".ascx":
                case ".master":
                case ".htm":
                case ".html":
                case ".xml":
                case ".skin":
                    return Language.Xml;
                case ".css":
                    return Language.Css;
                case ".sql":
                    return Language.Sql;
                default:
                     return Language.Xml; // xml is the default??

            }
        }

    }
}
